<template>
  <div class="video-poster-container">
    <!-- 视频元素（隐藏） -->
    <video
      ref="videoRef"
      :src="videoSrc"
      preload="metadata"
      muted
      playsinline
      @loadedmetadata="onVideoLoaded"
      @loadeddata="onVideoDataLoaded"
      @canplay="onVideoCanPlay"
      @error="onVideoError"
      style="display: none;"
    ></video>
    
    <!-- 显示区域 -->
    <div class="video-display" :style="{ width: width, height: height }">
      <!-- 如果有poster图片，优先显示 -->
      <img 
        v-if="posterImage" 
        :src="posterImage" 
        :alt="alt"
        :style="{ width: '100%', height: '100%', objectFit: 'cover' }"
        @click="handleClick"
      />
      <!-- 否则显示canvas捕获的首帧 -->
      <canvas 
        v-else-if="capturedPoster"
        ref="canvasRef"
        :width="canvasWidth"
        :height="canvasHeight"
        :style="{ 
          width: '100%', 
          height: '100%', 
          objectFit: 'cover',
          display: 'block'
        }"
        @click="handleClick"
      ></canvas>
      <!-- 加载中状态 -->
      <div v-else class="loading-placeholder" @click="handleClick">
        <div class="loading-icon">📹</div>
        <div class="loading-text">加载中...</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'

const props = defineProps({
  videoSrc: {
    type: String,
    required: true
  },
  posterImage: {
    type: String,
    default: ''
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '100%'
  },
  alt: {
    type: String,
    default: '视频封面'
  },
  canvasWidth: {
    type: Number,
    default: 320
  },
  canvasHeight: {
    type: Number,
    default: 180
  }
})

const emit = defineEmits(['click', 'poster-ready'])

const videoRef = ref(null)
const canvasRef = ref(null)
const capturedPoster = ref('')
const isCapturing = ref(false)

// 视频加载完成时捕获首帧
const onVideoLoaded = async () => {
  if (props.posterImage || isCapturing.value) return
  
  try {
    isCapturing.value = true
    
    // 先设置capturedPoster为true，让canvas渲染到DOM
    capturedPoster.value = 'captured'
    
    // 等待DOM更新
    await nextTick()
    
    // 再捕获首帧
    await captureFirstFrame()
  } catch (error) {
    console.error('捕获视频首帧失败:', error)
  } finally {
    isCapturing.value = false
  }
}

// 视频加载错误
const onVideoError = (error) => {
  console.error('视频加载失败:', error)
}

// 视频数据加载完成
const onVideoDataLoaded = async () => {
  if (props.posterImage || isCapturing.value || capturedPoster.value) return
  
  console.log('视频数据加载完成，尝试捕获首帧')
  try {
    isCapturing.value = true
    capturedPoster.value = 'captured'
    await nextTick()
    await captureFirstFrame()
  } catch (error) {
    console.error('数据加载后捕获首帧失败:', error)
  } finally {
    isCapturing.value = false
  }
}

// 视频可以播放时
const onVideoCanPlay = async () => {
  if (props.posterImage || isCapturing.value || capturedPoster.value) return
  
  console.log('视频可以播放，尝试捕获首帧')
  try {
    isCapturing.value = true
    capturedPoster.value = 'captured'
    await nextTick()
    await captureFirstFrame()
  } catch (error) {
    console.error('可播放时捕获首帧失败:', error)
  } finally {
    isCapturing.value = false
  }
}

// 捕获视频首帧
const captureFirstFrame = async () => {
  if (!videoRef.value) return
  
  const video = videoRef.value
  
  // 等待视频数据加载
  if (video.readyState < 2) {
    await new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('视频加载超时'))
      }, 5000)
      
      const loadHandler = () => {
        if (video.readyState >= 2) {
          clearTimeout(timeout)
          video.removeEventListener('loadeddata', loadHandler)
          resolve()
        }
      }
      video.addEventListener('loadeddata', loadHandler)
    })
  }
  
  try {
    // 使用可见的canvas元素
    let canvas = canvasRef.value
    if (!canvas) {
      console.error('Canvas元素不存在，等待DOM渲染...')
      // 如果canvas还不存在，再等待一下
      await new Promise(resolve => setTimeout(resolve, 100))
      canvas = canvasRef.value
      if (!canvas) {
        console.error('Canvas元素仍然不存在')
        return
      }
    }
    
    const ctx = canvas.getContext('2d', { willReadFrequently: true })
    
    // 设置canvas尺寸
    canvas.width = props.canvasWidth
    canvas.height = props.canvasHeight
    
    console.log('开始绘制视频帧到canvas:', {
      videoWidth: video.videoWidth,
      videoHeight: video.videoHeight,
      canvasWidth: canvas.width,
      canvasHeight: canvas.height,
      readyState: video.readyState
    })
    
    // 确保视频有尺寸信息
    if (video.videoWidth === 0 || video.videoHeight === 0) {
      console.log('视频尺寸为0，等待视频元数据加载...')
      await new Promise((resolve) => {
        const metadataHandler = () => {
          video.removeEventListener('loadedmetadata', metadataHandler)
          resolve()
        }
        video.addEventListener('loadedmetadata', metadataHandler)
        // 设置超时
        setTimeout(() => {
          video.removeEventListener('loadedmetadata', metadataHandler)
          resolve()
        }, 2000)
      })
    }
    
    // 再次检查视频尺寸
    if (video.videoWidth === 0 || video.videoHeight === 0) {
      console.error('视频尺寸仍然为0，无法绘制')
      return
    }
    
    // 尝试播放视频到第一帧
    try {
      video.currentTime = 0.1 // 设置到0.1秒，避免黑屏
      await new Promise((resolve) => {
        const seekedHandler = () => {
          video.removeEventListener('seeked', seekedHandler)
          resolve()
        }
        video.addEventListener('seeked', seekedHandler)
        setTimeout(() => {
          video.removeEventListener('seeked', seekedHandler)
          resolve()
        }, 1000)
      })
    } catch (seekError) {
      console.log('设置视频时间失败，继续尝试绘制:', seekError)
    }
    
    // 清空canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    
    // 绘制视频帧到canvas - 使用视频的实际尺寸
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
    
    // 检查canvas是否有内容
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    const hasContent = imageData.data.some(pixel => pixel !== 0)
    
    console.log('Canvas绘制完成，是否有内容:', hasContent, {
      imageDataLength: imageData.data.length,
      nonZeroPixels: imageData.data.filter(pixel => pixel !== 0).length
    })
    
    if (!hasContent) {
      console.log('尝试使用临时video元素绘制...')
      // 如果canvas绘制失败，尝试使用临时video元素
      try {
        const tempVideo = document.createElement('video')
        tempVideo.src = props.videoSrc
        tempVideo.muted = true
        tempVideo.playsinline = true
        tempVideo.preload = 'metadata'
        
        await new Promise((resolve) => {
          tempVideo.addEventListener('loadeddata', () => {
            tempVideo.currentTime = 0.1
            tempVideo.addEventListener('seeked', () => {
              ctx.clearRect(0, 0, canvas.width, canvas.height)
              ctx.drawImage(tempVideo, 0, 0, canvas.width, canvas.height)
              
              const tempImageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
              const tempHasContent = tempImageData.data.some(pixel => pixel !== 0)
              console.log('临时video绘制结果:', tempHasContent)
              
              tempVideo.remove()
              resolve()
            }, { once: true })
          }, { once: true })
          
          setTimeout(() => {
            tempVideo.remove()
            resolve()
          }, 2000)
        })
      } catch (tempError) {
        console.error('临时video绘制失败:', tempError)
      }
    }
    
    emit('poster-ready', 'captured')
    console.log('成功捕获视频首帧并渲染到canvas')
  } catch (error) {
    console.error('绘制视频帧失败:', error)
  }
}

// 处理点击事件
const handleClick = () => {
  emit('click')
}

// 监听videoSrc变化
watch(() => props.videoSrc, (newSrc) => {
  if (newSrc && !props.posterImage) {
    capturedPoster.value = ''
    isCapturing.value = false
    // 重新加载视频
    if (videoRef.value) {
      videoRef.value.load()
    }
  }
})

// 组件卸载时清理资源
onBeforeUnmount(() => {
  // 清理canvas内容
  if (canvasRef.value) {
    const ctx = canvasRef.value.getContext('2d')
    ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height)
  }
})
</script>

<style scoped>
.video-poster-container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.video-display {
  position: relative;
  background-color: #f5f5f5;
}

.loading-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: #f0f0f0;
  color: #999;
}

.loading-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.loading-text {
  font-size: 12px;
}
</style> 